/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.repository.entity.methods;

import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.caf.generator.utils.ExpressionUtils;
import com.inspur.edp.cef.entity.condition.SortCondition;
import com.inspur.edp.cef.entity.entity.IEntityData;
import com.inspur.edp.cef.generator.DotNetToJavaStringHelper;
import com.inspur.edp.cef.generator.repository.base.assemblerGenerator.DataTypeAssemblerGenCtx;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import lombok.var;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.Statement;

import java.util.ArrayList;
import java.util.Arrays;

public class GetDefaultFilterConditionMethodGenerator extends ClassMethodGenerator {
    private static final String ConditionVarName = "condition";
    protected DataTypeAssemblerGenCtx assGenCtx;

    public GetDefaultFilterConditionMethodGenerator(DataTypeAssemblerGenCtx assGenCtx) {
        this.assGenCtx = assGenCtx;
    }

    private IGspCommonObject getCommonObject() {
        return (IGspCommonObject) assGenCtx.getDataType();
    }

    @Override
    protected Block buildMethodBody() {
        String sortCondition = getCommonObject().getOrderbyCondition();
        Block block = ast.newBlock();
        if (DotNetToJavaStringHelper.isNullOrEmpty(sortCondition)) {
            block.statements().add(getReturnNullStatement());
            return block;
        }
        ArrayList<Statement> statements = getFilterStatements(sortCondition);
        block.statements().addAll(statements);
        return block;
    }


    //    String condition = "";
	//    return new ObjectMapper().readValue(condition, ArrayList<SortCondition> .class);
    private ArrayList<Statement> getFilterStatements(String sortCondition) {
        ArrayList<Statement> statements = new ArrayList<Statement>();
        Statement conditionStatement = getConditionStatement(sortCondition);
        statements.add(conditionStatement);

        ReturnStatement serializeStatement = getSerializeStatement();
        statements.add(serializeStatement);

        return statements;
    }

    private Statement getConditionStatement(String sortCondition) {
        var frag = ast.newVariableDeclarationFragment();
        frag.setName(ast.newSimpleName(ConditionVarName));
        var value = ast.newStringLiteral();
        value.setLiteralValue(sortCondition);
        frag.setInitializer(value);

        var statement = ast.newVariableDeclarationStatement(frag);
        statement.setType(ast.newSimpleType(ast.newSimpleName("String")));
        return statement;
//        return SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(
//                SyntaxFactory.IdentifierName("var")).WithVariables(
//                        SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator
//                                (SyntaxFactory.Identifier(ConditionVarName)).
//                                WithInitializer(SyntaxFactory.EqualsValueClause
//                                        (SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression,
//                                                SyntaxFactory.Literal(sortCondition)))))));
    }

    private ReturnStatement getSerializeStatement() {
        var returnStatement = ast.newReturnStatement();
        var methodInvocation = ast.newMethodInvocation();
        methodInvocation.setName(ast.newSimpleName("readValue"));

        var classCreation = ast.newClassInstanceCreation();
        classCreation.setType(ast.newSimpleType(ast.newSimpleName("ObjectMapper")));
        methodInvocation.setExpression(classCreation);

        methodInvocation.arguments().add(ast.newSimpleName(ConditionVarName));

        var arg2 = ast.newMethodInvocation();
        arg2.setName(ast.newSimpleName("getClass"));
        var argCreation = ast.newClassInstanceCreation();

        var agrType = ast.newParameterizedType(
                ast.newSimpleType(ast.newSimpleName("ArrayList"))
        );
        agrType.typeArguments().add(
                ast.newSimpleType(ast.newSimpleName("SortCondition"))
        );
        argCreation.setType(agrType);
        arg2.setExpression(argCreation);
        methodInvocation.arguments().add(arg2);
        returnStatement.setExpression(methodInvocation);


        return returnStatement;
//        return SyntaxFactory.ReturnStatement(SyntaxFactory.BinaryExpression(
//                SyntaxKind.AsExpression, SyntaxFactory.InvocationExpression(
//                        SyntaxFactory.MemberAccessExpression(
//                                SyntaxKind.SimpleMemberAccessExpression,
//                                TypeUtils.getTypeSyntax(JsonConvert.class),
//                                SyntaxFactory.IdentifierName("DeserializeObject"))).
//                        WithArgumentList(SyntaxFactory.ArgumentList(
//                                SyntaxFactory.<ArgumentSyntax>SeparatedList(
//                                        new SyntaxNodeOrToken[]{SyntaxFactory.Argument(
//                                                SyntaxFactory.IdentifierName(ConditionVarName)),
//                                                SyntaxFactory.Token(SyntaxKind.CommaToken),
//                                                SyntaxFactory.Argument(
//                                                        SyntaxFactory.TypeOfExpression(TypeUtils.getTypeSyntax(
//                                                                ArrayList<SortCondition>.class)))}))), TypeUtils.getTypeSyntax(ArrayList<SortCondition>.class)));
    }

    private ReturnStatement getReturnNullStatement() {
        return ExpressionUtils.getReturnNullStatement(ast);
    }

    @Override
    protected ArrayList<Modifier.ModifierKeyword> getAccessModifiers() {
        return new ArrayList<Modifier.ModifierKeyword>(Arrays.asList(
                new Modifier.ModifierKeyword[]{Modifier.ModifierKeyword.PROTECTED_KEYWORD}));
    }

    @Override
    protected boolean getIsOverride() {
        return true;
    }

    @Override
    protected String getMethodName() {
        return "getDefaultSortCondition";
    }

    @Override
    protected ArrayList<ParameterInfo> getParameterCollection() {
        return new ArrayList<ParameterInfo>();
    }

    @Override
    protected TypeInfo getReturnType() {
        //TODO: caf暂不支持, 主动加import
        assGenCtx.getRepoGenCtx().addImport(ArrayList.class.getName());
        assGenCtx.getRepoGenCtx().addImport(SortCondition.class.getName());
        var typeInfo = new TypeInfo(ArrayList.class);
        typeInfo.setIsParameterizedType(true);
        var arg = new TypeInfo(SortCondition.class);
        typeInfo.getArguments().add(arg);

        return typeInfo;
    }
}
